home *** CD-ROM | disk | FTP | other *** search
/ Aminet 23 / Aminet 23 (1998)(GTI - Schatztruhe)[!][Feb 1998].iso / Aminet / misc / emu / amiSPIMsrc.lha / parser.y < prev    next >
Text File  |  1994-01-17  |  42KB  |  2,342 lines

  1. /* SPIM S20 MIPS simulator.
  2.    Parser for instructions and assembler directives.
  3.    Copyright (C) 1990-1994 by James Larus (larus@cs.wisc.edu).
  4.    ALL RIGHTS RESERVED.
  5.  
  6.    SPIM is distributed under the following conditions:
  7.  
  8.      You may make copies of SPIM for your own use and modify those copies.
  9.  
  10.      All copies of SPIM must retain my name and copyright notice.
  11.  
  12.      You may not sell SPIM or distributed SPIM in conjunction with a
  13.      commerical product or service without the expressed written consent of
  14.      James Larus.
  15.  
  16.    THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  17.    IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  18.    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  19.    PURPOSE. */
  20.  
  21.  
  22. /* $Header: /home/primost/larus/Software/SPIM/RCS/parser.y,v 1.64 1994/01/18 03:21:45 larus Exp larus $
  23. */
  24.  
  25.  
  26.  
  27. %start LINE
  28.  
  29. %token Y_NL
  30. %token Y_INT
  31. %token Y_ID
  32. %token Y_REG
  33. %token Y_FP_REG
  34. %token Y_STR
  35. %token Y_FP
  36.  
  37. /* MIPS instructions op codes: */
  38.  
  39. %token Y_ABS_D_OP
  40. %token Y_ABS_S_OP
  41. %token Y_ADDIU_OP
  42. %token Y_ADDI_OP
  43. %token Y_ADDU_OP
  44. %token Y_ADD_D_OP
  45. %token Y_ADD_OP
  46. %token Y_ADD_S_OP
  47. %token Y_ANDI_OP
  48. %token Y_AND_OP
  49. %token Y_BC0F_OP
  50. %token Y_BC0T_OP
  51. %token Y_BC1F_OP
  52. %token Y_BC1T_OP
  53. %token Y_BC2F_OP
  54. %token Y_BC2T_OP
  55. %token Y_BC3F_OP
  56. %token Y_BC3T_OP
  57. %token Y_BEQ_OP
  58. %token Y_BGEZAL_OP
  59. %token Y_BGEZ_OP
  60. %token Y_BGTZ_OP
  61. %token Y_BLEZ_OP
  62. %token Y_BLTZAL_OP
  63. %token Y_BLTZ_OP
  64. %token Y_BNE_OP
  65. %token Y_BREAK_OP
  66. %token Y_CFC0_OP
  67. %token Y_CFC1_OP
  68. %token Y_CFC2_OP
  69. %token Y_CFC3_OP
  70. %token Y_COP0_OP
  71. %token Y_COP1_OP
  72. %token Y_COP2_OP
  73. %token Y_COP3_OP
  74. %token Y_CTC0_OP
  75. %token Y_CTC1_OP
  76. %token Y_CTC2_OP
  77. %token Y_CTC3_OP
  78. %token Y_CVT_D_S_OP
  79. %token Y_CVT_D_W_OP
  80. %token Y_CVT_S_D_OP
  81. %token Y_CVT_S_W_OP
  82. %token Y_CVT_W_D_OP
  83. %token Y_CVT_W_S_OP
  84. %token Y_C_EQ_D_OP
  85. %token Y_C_EQ_S_OP
  86. %token Y_C_F_D_OP
  87. %token Y_C_F_S_OP
  88. %token Y_C_LE_D_OP
  89. %token Y_C_LE_S_OP
  90. %token Y_C_LT_D_OP
  91. %token Y_C_LT_S_OP
  92. %token Y_C_NGE_D_OP
  93. %token Y_C_NGE_S_OP
  94. %token Y_C_NGLE_D_OP
  95. %token Y_C_NGLE_S_OP
  96. %token Y_C_NGL_D_OP
  97. %token Y_C_NGL_S_OP
  98. %token Y_C_NGT_D_OP
  99. %token Y_C_NGT_S_OP
  100. %token Y_C_OLE_D_OP
  101. %token Y_C_OLE_S_OP
  102. %token Y_C_SEQ_D_OP
  103. %token Y_C_SEQ_S_OP
  104. %token Y_C_SF_D_OP
  105. %token Y_C_SF_S_OP
  106. %token Y_C_UEQ_D_OP
  107. %token Y_C_UEQ_S_OP
  108. %token Y_C_ULE_D_OP
  109. %token Y_C_ULE_S_OP
  110. %token Y_C_UN_D_OP
  111. %token Y_C_UN_S_OP
  112. %token Y_DIVU_OP
  113. %token Y_DIV_D_OP
  114. %token Y_DIV_OP
  115. %token Y_DIV_S_OP
  116. %token Y_JALR_OP
  117. %token Y_JAL_OP
  118. %token Y_JR_OP
  119. %token Y_J_OP
  120. %token Y_LBU_OP
  121. %token Y_LB_OP
  122. %token Y_LHU_OP
  123. %token Y_LH_OP
  124. %token Y_LUI_OP
  125. %token Y_LWC0_OP
  126. %token Y_LWC1_OP
  127. %token Y_LWC2_OP
  128. %token Y_LWC3_OP
  129. %token Y_LWL_OP
  130. %token Y_LWR_OP
  131. %token Y_LW_OP
  132. %token Y_MFC0_OP
  133. %token Y_MFC1_OP
  134. %token Y_MFC2_OP
  135. %token Y_MFC3_OP
  136. %token Y_MFHI_OP
  137. %token Y_MFLO_OP
  138. %token Y_MOV_D_OP
  139. %token Y_MOV_S_OP
  140. %token Y_MTC0_OP
  141. %token Y_MTC1_OP
  142. %token Y_MTC2_OP
  143. %token Y_MTC3_OP
  144. %token Y_MTHI_OP
  145. %token Y_MTLO_OP
  146. %token Y_MULTU_OP
  147. %token Y_MULT_OP
  148. %token Y_MUL_D_OP
  149. %token Y_MUL_S_OP
  150. %token Y_NEG_D_OP
  151. %token Y_NEG_S_OP
  152. %token Y_NOR_OP
  153. %token Y_ORI_OP
  154. %token Y_OR_OP
  155. %token Y_PFW_OP
  156. %token Y_RFE_OP
  157. %token Y_SB_OP
  158. %token Y_SH_OP
  159. %token Y_SLLV_OP
  160. %token Y_SLL_OP
  161. %token Y_SLTIU_OP
  162. %token Y_SLTI_OP
  163. %token Y_SLTU_OP
  164. %token Y_SLT_OP
  165. %token Y_SRAV_OP
  166. %token Y_SRA_OP
  167. %token Y_SRLV_OP
  168. %token Y_SRL_OP
  169. %token Y_SUBU_OP
  170. %token Y_SUB_D_OP
  171. %token Y_SUB_OP
  172. %token Y_SUB_S_OP
  173. %token Y_SWC0_OP
  174. %token Y_SWC1_OP
  175. %token Y_SWC2_OP
  176. %token Y_SWC3_OP
  177. %token Y_SWL_OP
  178. %token Y_SWR_OP
  179. %token Y_SW_OP
  180. %token Y_SYSCALL_OP
  181. %token Y_TLBP_OP
  182. %token Y_TLBR_OP
  183. %token Y_TLBWI_OP
  184. %token Y_TLBWR_OP
  185. %token Y_XORI_OP
  186. %token Y_XOR_OP
  187.  
  188.  
  189. /* Assembler pseudo operations op codes: */
  190.  
  191. %token Y_ABS_POP
  192. %token Y_BAL_POP
  193. %token Y_BEQZ_POP
  194. %token Y_BGEU_POP
  195. %token Y_BGE_POP
  196. %token Y_BGTU_POP
  197. %token Y_BGT_POP
  198. %token Y_BLEU_POP
  199. %token Y_BLE_POP
  200. %token Y_BLTU_POP
  201. %token Y_BLT_POP
  202. %token Y_BNEZ_POP
  203. %token Y_B_POP
  204. %token Y_LA_POP
  205. %token Y_LD_POP
  206. %token Y_LI_POP
  207. %token Y_LI_D_POP
  208. %token Y_LI_S_POP
  209. %token Y_L_D_POP
  210. %token Y_L_S_POP
  211. %token Y_MFC1_D_POP
  212. %token Y_MTC1_D_POP
  213. %token Y_MOVE_POP
  214. %token Y_MULOU_POP
  215. %token Y_MULO_POP
  216. %token Y_MUL_POP
  217. %token Y_NEGU_POP
  218. %token Y_NEG_POP
  219. %token Y_NOP_POP
  220. %token Y_NOT_POP
  221. %token Y_REMU_POP
  222. %token Y_REM_POP
  223. %token Y_ROL_POP
  224. %token Y_ROR_POP
  225. %token Y_SD_POP
  226. %token Y_SEQ_POP
  227. %token Y_SGEU_POP
  228. %token Y_SGE_POP
  229. %token Y_SGTU_POP
  230. %token Y_SGT_POP
  231. %token Y_SLEU_POP
  232. %token Y_SLE_POP
  233. %token Y_SNE_POP
  234. %token Y_S_D_POP
  235. %token Y_S_S_POP
  236. %token Y_ULHU_POP
  237. %token Y_ULH_POP
  238. %token Y_ULW_POP
  239. %token Y_USH_POP
  240. %token Y_USW_POP
  241.  
  242. /* Assembler directives: */
  243.  
  244. %token Y_ALIAS_DIR
  245. %token Y_ALIGN_DIR
  246. %token Y_ASCII_DIR
  247. %token Y_ASCIIZ_DIR
  248. %token Y_ASM0_DIR
  249. %token Y_BGNB_DIR
  250. %token Y_BYTE_DIR
  251. %token Y_COMM_DIR
  252. %token Y_DATA_DIR
  253. %token Y_DOUBLE_DIR
  254. %token Y_ENDB_DIR
  255. %token Y_ENDR_DIR
  256. %token Y_END_DIR
  257. %token Y_ENT_DIR
  258. %token Y_ERR_DIR
  259. %token Y_EXTERN_DIR
  260. %token Y_FILE_DIR
  261. %token Y_FLOAT_DIR
  262. %token Y_FMASK_DIR
  263. %token Y_FRAME_DIR
  264. %token Y_GLOBAL_DIR
  265. %token Y_HALF_DIR
  266. %token Y_K_TEXT_DIR
  267. %token Y_K_DATA_DIR
  268. %token Y_LABEL_DIR
  269. %token Y_LCOMM_DIR
  270. %token Y_LIVEREG_DIR
  271. %token Y_LOC_DIR
  272. %token Y_MASK_DIR
  273. %token Y_NOALIAS_DIR
  274. %token Y_OPTIONS_DIR
  275. %token Y_RDATA_DIR
  276. %token Y_REPEAT_DIR
  277. %token Y_SDATA_DIR
  278. %token Y_SET_DIR
  279. %token Y_SPACE_DIR
  280. %token Y_STRUCT_DIR
  281. %token Y_TEXT_DIR
  282. %token Y_VERSTAMP_DIR
  283. %token Y_VREG_DIR
  284. %token Y_WORD_DIR
  285.  
  286. %{
  287. #include <stdio.h>
  288.  
  289. #include "spim.h"
  290. #include "spim-utils.h"
  291. #include "inst.h"
  292. #include "mem.h"
  293. #include "reg.h"
  294. #include "sym-tbl.h"
  295. #include "data.h"
  296. #include "scanner.h"
  297. #include "parser.h"
  298.  
  299.  
  300. /* return (0) */
  301. #define LINE_PARSE_DONE YYACCEPT
  302.  
  303. /* return (1) */
  304. #define FILE_PARSE_DONE YYABORT
  305.  
  306. typedef struct ll
  307. {
  308.   label *head;
  309.   struct ll *tail;
  310. } label_list;
  311.  
  312.  
  313. /* Exported Variables: */
  314.  
  315. int data_dir;            /* Non-zero means item in data segment */
  316.  
  317. int text_dir;            /* Non-zero means item in text segment */
  318.  
  319.  
  320. /* Local functions: */
  321.  
  322. #ifdef __STDC__
  323. static imm_expr *branch_offset (int n_inst);
  324. static void clear_labels (void);
  325. static label_list *cons_label (label *head, label_list *tail);
  326. static void div_inst (int op, int rd, int rs, int rt, int const_divisor);
  327. static void mult_inst (int op, int rd, int rs, int rt);
  328. static void nop_inst (void);
  329. static void set_eq_inst (int op, int rd, int rs, int rt);
  330. static void set_ge_inst (int op, int rd, int rs, int rt);
  331. static void set_gt_inst (int op, int rd, int rs, int rt);
  332. static void set_le_inst (int op, int rd, int rs, int rt);
  333. static void store_word_data (int value);
  334. static void trap_inst (void);
  335. #else
  336. static imm_expr *branch_offset ();
  337. static void clear_labels ();
  338. static label_list *cons_label ();
  339. static void div_inst ();
  340. static void mult_inst ();
  341. static void nop_inst ();
  342. static void set_eq_inst ();
  343. static void set_ge_inst ();
  344. static void set_gt_inst ();
  345. static void set_le_inst ();
  346. static void store_word_data ();
  347. static void trap_inst ();
  348. #endif
  349.  
  350.  
  351. /* Local variables: */
  352.  
  353. static int null_term;        /* Non-zero means string terminate by \0 */
  354.  
  355. static void (*store_op) ();    /* Function to store items in an EXPR_LST */
  356.  
  357. static label_list *this_line_labels = NULL; /* List of label for curent line */
  358.  
  359. static int noat_flag = 0;    /* Non-zero means program can use $1 */
  360.  
  361. static char *input_file_name;    /* Name of file being parsed */
  362.  
  363.  
  364. %}
  365.  
  366.  
  367.  
  368. %%
  369.  
  370. LINE:        {scanner_start_line (); clear_labels ();} OPT_LBL 
  371.         CMD
  372.     ;
  373.  
  374.  
  375. OPT_LBL:    ID ':' {
  376.                this_line_labels =
  377.                  cons_label (record_label
  378.                      ((char *)$1,
  379.                       (text_dir ? current_text_pc ()
  380.                        : current_data_pc ())),
  381.                      this_line_labels);
  382.              }
  383.  
  384.     |    ID '=' Y_INT
  385.         {
  386.           label *l = record_label ((char *) $1, (mem_addr) $3);
  387.  
  388.           l->const_flag = 1;
  389.           clear_labels ();
  390.         }
  391.  
  392.     |
  393.     ;
  394.  
  395.  
  396. CMD:        ASM_CODE Y_NL
  397.         {
  398.           clear_labels ();
  399.           LINE_PARSE_DONE;
  400.         }
  401.  
  402.     |    ASM_DIRECTIVE    Y_NL
  403.         {
  404.           clear_labels ();
  405.           LINE_PARSE_DONE;
  406.         }
  407.  
  408.     |    Y_NL
  409.         {
  410.           clear_labels ();
  411.           LINE_PARSE_DONE;
  412.         }
  413.     |
  414.         {
  415.           clear_labels ();
  416.           FILE_PARSE_DONE;
  417.         }
  418.     ;
  419.  
  420.  
  421.  
  422. ASM_CODE:    LOAD_OP        DEST_REG    ADDRESS
  423.         {
  424.           i_type_inst ($1 == Y_LD_POP ? Y_LW_OP : $1,
  425.                    $2,
  426.                    addr_expr_reg ((addr_expr *)$3),
  427.                    addr_expr_imm ((addr_expr *)$3));
  428.           if ($1 == Y_LD_POP)
  429.             i_type_inst_free (Y_LW_OP,
  430.                       $2 + 1,
  431.                       addr_expr_reg ((addr_expr *)$3),
  432.                       incr_expr_offset (addr_expr_imm ((addr_expr *)$3),
  433.                             4));
  434.           free (((addr_expr *)$3)->imm);
  435.           free ((addr_expr *)$3);
  436.         }
  437.  
  438.     |    LOAD_COP    COP_REG        ADDRESS
  439.         {
  440.           i_type_inst ($1, $2, addr_expr_reg ((addr_expr *)$3),
  441.                    addr_expr_imm ((addr_expr *)$3));
  442.           free (((addr_expr *)$3)->imm);
  443.           free ((addr_expr *)$3);
  444.         }
  445.  
  446.     |    LOAD_IMM_OP    DEST_REG    IMM
  447.         {
  448.           i_type_inst_free ($1, $2, 0, (imm_expr *)$3);
  449.         }
  450.  
  451.  
  452.     |    Y_LA_POP    DEST_REG    ADDRESS
  453.         {
  454.           if (addr_expr_reg ((addr_expr *)$3))
  455.             i_type_inst (Y_ADDI_OP, $2,
  456.                  addr_expr_reg ((addr_expr *)$3),
  457.                  addr_expr_imm ((addr_expr *)$3));
  458.           else
  459.             i_type_inst (Y_LUI_OP, $2, 0,
  460.                  addr_expr_imm ((addr_expr *)$3));
  461.           free (((addr_expr *)$3)->imm);
  462.           free ((addr_expr *)$3);
  463.         }
  464.  
  465.  
  466.     |    Y_LI_POP    DEST_REG    IMM
  467.         {
  468.           i_type_inst_free (Y_ORI_OP, $2, 0, (imm_expr *)$3);
  469.         }
  470.  
  471.  
  472.     |    Y_LI_D_POP    F_DEST        Y_FP
  473.         {
  474.           int *x = (int *) $3;
  475.  
  476.           i_type_inst (Y_ORI_OP, 1, 0, const_imm_expr (*x));
  477.           r_type_inst (Y_MTC1_OP, $2, 0, 1);
  478.           i_type_inst (Y_ORI_OP, 1, 0, const_imm_expr (*(x+1)));
  479.           r_type_inst (Y_MTC1_OP, $2 + 1, 0, 1);
  480.         }
  481.  
  482.  
  483.     |    Y_LI_S_POP    F_DEST        Y_FP
  484.         {
  485.           float x = * ((double *) $3);
  486.           int *y = (int *) &x;
  487.  
  488.           i_type_inst (Y_ORI_OP, 1, 0, const_imm_expr (*y));
  489.           r_type_inst (Y_MTC1_OP, $2, 0, 1);
  490.         }
  491.  
  492.  
  493.     |    Y_ULW_POP    DEST_REG    ADDRESS
  494.         {
  495. #ifdef BIGENDIAN
  496.           i_type_inst (Y_LWL_OP, $2,
  497.                    addr_expr_reg ((addr_expr *)$3),
  498.                    addr_expr_imm ((addr_expr *)$3));
  499.           i_type_inst_free (Y_LWR_OP, $2,
  500.                     addr_expr_reg ((addr_expr *)$3),
  501.                     incr_expr_offset (addr_expr_imm ((addr_expr *)$3),
  502.                               3));
  503. #else
  504.           i_type_inst_free (Y_LWL_OP, $2,
  505.                     addr_expr_reg ((addr_expr *)$3),
  506.                     incr_expr_offset (addr_expr_imm ((addr_expr *)$3),
  507.                               3));
  508.           i_type_inst (Y_LWR_OP, $2,
  509.                    addr_expr_reg ((addr_expr *)$3),
  510.                    addr_expr_imm ((addr_expr *)$3));
  511. #endif
  512.           free (((addr_expr *)$3)->imm);
  513.           free ((addr_expr *)$3);
  514.         }
  515.  
  516.  
  517.     |    ULOADH_POP    DEST_REG    ADDRESS
  518.         {
  519. #ifdef BIGENDIAN
  520.           i_type_inst (($1 == Y_ULH_POP ? Y_LB_OP : Y_LBU_OP),
  521.                    $2,
  522.                    addr_expr_reg ((addr_expr *)$3),
  523.                    addr_expr_imm ((addr_expr *)$3));
  524.           i_type_inst_free (Y_LBU_OP, 1,
  525.                     addr_expr_reg ((addr_expr *)$3),
  526.                     incr_expr_offset (addr_expr_imm ((addr_expr *)$3),
  527.                               1));
  528. #else
  529.           i_type_inst_free (($1 == Y_ULH_POP ? Y_LB_OP : Y_LBU_OP),
  530.                     $2,
  531.                     addr_expr_reg ((addr_expr *)$3),
  532.                     incr_expr_offset (addr_expr_imm ((addr_expr *)$3),
  533.                               1));
  534.           i_type_inst (Y_LBU_OP, 1,
  535.                    addr_expr_reg ((addr_expr *)$3),
  536.                    addr_expr_imm ((addr_expr *)$3));
  537. #endif
  538.           r_sh_type_inst (Y_SLL_OP, $2, $2, 8);
  539.           r_type_inst (Y_OR_OP, $2, $2, 1);
  540.           free (((addr_expr *)$3)->imm);
  541.           free ((addr_expr *)$3);
  542.         }
  543.  
  544.  
  545.     |    LOADF_OP    F_DEST        ADDRESS
  546.         {
  547.           i_type_inst (Y_LWC1_OP, $2,
  548.                    addr_expr_reg ((addr_expr *)$3),
  549.                    addr_expr_imm ((addr_expr *)$3));
  550.           if ($1 == Y_L_D_POP)
  551.             i_type_inst_free (Y_LWC1_OP, $2 + 1,
  552.                       addr_expr_reg ((addr_expr *)$3),
  553.                       incr_expr_offset (addr_expr_imm ((addr_expr *)$3),
  554.                             4));
  555.           free (((addr_expr *)$3)->imm);
  556.           free ((addr_expr *)$3);
  557.         }
  558.  
  559.  
  560.     |    STORE_OP    SOURCE        ADDRESS
  561.         {
  562.           i_type_inst ($1 == Y_SD_POP ? Y_SW_OP : $1,
  563.                    $2,
  564.                    addr_expr_reg ((addr_expr *)$3),
  565.                    addr_expr_imm ((addr_expr *)$3));
  566.           if ($1 == Y_SD_POP)
  567.             i_type_inst_free (Y_SW_OP, $2 + 1,
  568.                       addr_expr_reg ((addr_expr *)$3),
  569.                       incr_expr_offset (addr_expr_imm ((addr_expr *)$3),
  570.                             4));
  571.           free (((addr_expr *)$3)->imm);
  572.           free ((addr_expr *)$3);
  573.         }
  574.  
  575.  
  576.     |    STORE_COP    COP_REG        ADDRESS
  577.         {
  578.           i_type_inst ($1, $2,
  579.                    addr_expr_reg ((addr_expr *)$3),
  580.                    addr_expr_imm ((addr_expr *)$3));
  581.           free (((addr_expr *)$3)->imm);
  582.           free ((addr_expr *)$3);
  583.         }
  584.  
  585.  
  586.     |    Y_USW_POP    SOURCE        ADDRESS
  587.         {
  588. #ifdef BIGENDIAN
  589.           i_type_inst (Y_SWL_OP, $2,
  590.                    addr_expr_reg ((addr_expr *)$3),
  591.                    addr_expr_imm ((addr_expr *)$3));
  592.           i_type_inst_free (Y_SWR_OP, $2,
  593.                     addr_expr_reg ((addr_expr *)$3),
  594.                     incr_expr_offset (addr_expr_imm ((addr_expr *)$3),
  595.                               3));
  596. #else
  597.           i_type_inst_free (Y_SWL_OP, $2,
  598.                     addr_expr_reg ((addr_expr *)$3),
  599.                     incr_expr_offset (addr_expr_imm ((addr_expr *)$3),
  600.                               3));
  601.           i_type_inst (Y_SWR_OP, $2,
  602.                    addr_expr_reg ((addr_expr *)$3),
  603.                    addr_expr_imm ((addr_expr *)$3));
  604. #endif
  605.           free (((addr_expr *)$3)->imm);
  606.           free ((addr_expr *)$3);
  607.         }
  608.  
  609.  
  610.     |    Y_USH_POP    SOURCE        ADDRESS
  611.         {
  612.           i_type_inst (Y_SB_OP, $2,
  613.                    addr_expr_reg ((addr_expr *)$3),
  614.                    addr_expr_imm ((addr_expr *)$3));
  615.           r_sh_type_inst (Y_SRL_OP, 1, $2, 8);
  616.           i_type_inst_free (Y_SB_OP, 1,
  617.                     addr_expr_reg ((addr_expr *)$3),
  618.                     incr_expr_offset (addr_expr_imm ((addr_expr *)$3),
  619.                               1));
  620.           free (((addr_expr *)$3)->imm);
  621.           free ((addr_expr *)$3);
  622.         }
  623.  
  624.  
  625.     |    STOREF_OP    F_SRC1        ADDRESS
  626.         {
  627.           i_type_inst (Y_SWC1_OP, $2,
  628.                    addr_expr_reg ((addr_expr *)$3),
  629.                    addr_expr_imm ((addr_expr *)$3));
  630.           if ($1 == Y_S_D_POP)
  631.             i_type_inst_free (Y_SWC1_OP, $2 + 1,
  632.                       addr_expr_reg ((addr_expr *)$3),
  633.                       incr_expr_offset (addr_expr_imm ((addr_expr *)$3),
  634.                             4));
  635.           free (((addr_expr *)$3)->imm);
  636.           free ((addr_expr *)$3);
  637.         }
  638.  
  639.  
  640.     |    SYS_OP
  641.         {
  642.           r_type_inst ($1, 0, 0, 0);
  643.         }
  644.  
  645.  
  646.     |    Y_BREAK_OP        Y_INT
  647.         {
  648.           if ($2 == 1)
  649.             yyerror ("Breakpoint 1 is reserved for debugger");
  650.           r_type_inst ($1, $2, 0, 0);
  651.         }
  652.  
  653.  
  654.     |    Y_NOP_POP
  655.         {
  656.           nop_inst ();
  657.         }
  658.  
  659.  
  660.     |    Y_ABS_POP        DEST_REG    SRC1
  661.         {
  662.           if ($2 != $3)
  663.             r_type_inst (Y_ADDU_OP, $2, 0, $3);
  664.  
  665.           i_type_inst_free (Y_BGEZ_OP, 0, $3, branch_offset (2));
  666.           r_type_inst (Y_SUB_OP, $2, 0, $3);
  667.         }
  668.  
  669.  
  670.     |    Y_NEG_POP        DEST_REG    SRC1
  671.         {
  672.           r_type_inst (Y_SUB_OP, $2, 0, $3);
  673.         }
  674.  
  675.  
  676.     |    Y_NEGU_POP        DEST_REG    SRC1
  677.         {
  678.           r_type_inst (Y_SUBU_OP, $2, 0, $3);
  679.         }
  680.  
  681.  
  682.     |    Y_NOT_POP        DEST_REG    SRC1
  683.         {
  684.           r_type_inst (Y_NOR_OP, $2, $3, 0);
  685.         }
  686.  
  687.  
  688.     |    Y_MOVE_POP        DEST_REG    SRC1
  689.         {
  690.           r_type_inst (Y_ADDU_OP, $2, 0, $3);
  691.         }
  692.  
  693.  
  694.     |    BINARY_OP_I    DEST_REG    SRC1        SRC2
  695.         {
  696.           r_type_inst ($1, $2, $3, $4);
  697.         }
  698.  
  699.  
  700.     |    BINARY_OP_I    DEST_REG    SRC1        IMM
  701.         {
  702.           i_type_inst_free (op_to_imm_op ($1), $2, $3, (imm_expr *)$4);
  703.         }
  704.  
  705.  
  706.     |    BINARY_OP_I    DEST_REG    IMM
  707.         {
  708.           i_type_inst_free (op_to_imm_op ($1), $2, $2, (imm_expr *)$3);
  709.         }
  710.  
  711.  
  712.     |    BINARY_OPR_I    DEST_REG    SRC1        SRC2
  713.         {
  714.           r_type_inst ($1, $2, $4, $3);
  715.         }
  716.  
  717.  
  718.     |    BINARY_OPR_I    DEST_REG    SRC1        Y_INT
  719.         {
  720.           r_sh_type_inst (op_to_imm_op ($1), $2, $3, $4);
  721.         }
  722.  
  723.  
  724.     |    BINARY_OPR_I    DEST_REG    Y_INT
  725.         {
  726.           r_sh_type_inst (op_to_imm_op ($1), $2, $2, $3);
  727.         }
  728.  
  729.  
  730.     |    BINARY_IMM_OP    DEST_REG    SRC1        IMM
  731.         {
  732.           i_type_inst_free ($1, $2, $3, (imm_expr *)$4);
  733.         }
  734.  
  735.  
  736.     |    BINARY_IMM_OP    DEST_REG    IMM
  737.         {
  738.           i_type_inst_free ($1, $2, $2, (imm_expr *)$3);
  739.         }
  740.  
  741.  
  742.     |    SHIFT_OP    DEST_REG    SRC1        Y_INT
  743.         {
  744.           r_sh_type_inst ($1, $2, $3, $4);
  745.         }
  746.  
  747.  
  748.     |    SHIFT_OP    DEST_REG    SRC1        SRC2
  749.         {
  750.           r_type_inst (imm_op_to_op ($1), $2, $3, $4);
  751.         }
  752.  
  753.  
  754.     |    BINARY_OP_NOI    DEST_REG    SRC1        SRC2
  755.         {
  756.           r_type_inst ($1, $2, $3, $4);
  757.         }
  758.  
  759.  
  760.     |    BINARY_OP_NOI    DEST_REG    SRC1        IMM
  761.         {
  762.           if (bare_machine)
  763.             yyerror ("Immediate form not allowed in bare machine");
  764.           else
  765.             {
  766.               if (!zero_imm ((imm_expr *)$4))
  767.             /* Use $at */
  768.             i_type_inst (Y_ORI_OP, 1, 0, (imm_expr *)$4);
  769.               r_type_inst ($1,
  770.                    $2,
  771.                    $3,
  772.                    (zero_imm ((imm_expr *)$4) ? 0 : 1));
  773.             }
  774.           free ((imm_expr *)$4);
  775.         }
  776.  
  777.  
  778.     |    BINARY_OP_NOI    DEST_REG    IMM
  779.         {
  780.           if (bare_machine)
  781.             yyerror ("Immediate form not allowed in bare machine");
  782.           else
  783.             {
  784.               if (!zero_imm ((imm_expr *)$3))
  785.             /* Use $at */
  786.             i_type_inst (Y_ORI_OP, 1, 0, (imm_expr *)$3);
  787.               r_type_inst ($1,
  788.                    $2,
  789.                    $2,
  790.                    (zero_imm ((imm_expr *)$3) ? 0 : 1));
  791.             }
  792.           free ((imm_expr *)$3);
  793.         }
  794.  
  795.  
  796.     |    SUB_OP    DEST_REG    SRC1        SRC2
  797.         {
  798.           r_type_inst ($1, $2, $3, $4);
  799.         }
  800.  
  801.  
  802.     |    SUB_OP    DEST_REG    SRC1        IMM
  803.         {
  804.           int val = eval_imm_expr ($4);
  805.  
  806.           if (bare_machine)
  807.             yyerror ("Immediate form not allowed in bare machine");
  808.           else
  809.             i_type_inst ($1 == Y_SUB_OP ? Y_ADDI_OP
  810.                  : $1 == Y_SUBU_OP ? Y_ADDIU_OP
  811.                  : (fatal_error ("Bad SUB_OP\n"), 0),
  812.                  $2,
  813.                  $3,
  814.                  make_imm_expr ( -val, NULL, 0));
  815.           free ((imm_expr *)$4);
  816.         }
  817.  
  818.  
  819.     |    SUB_OP    DEST_REG    IMM
  820.         {
  821.           int val = eval_imm_expr ($3);
  822.  
  823.           if (bare_machine)
  824.             yyerror ("Immediate form not allowed in bare machine");
  825.           else
  826.             i_type_inst ($1 == Y_SUB_OP ? Y_ADDI_OP
  827.                  : $1 == Y_SUBU_OP ? Y_ADDIU_OP
  828.                  : (fatal_error ("Bad SUB_OP\n"), 0),
  829.                  $2,
  830.                  $2,
  831.                  make_imm_expr (-val, NULL, 0));
  832.           free ((imm_expr *)$3);
  833.         }
  834.  
  835.  
  836.     |    DIV_POP        DEST_REG    SRC1
  837.         {
  838.           /* The hardware divide operation (ignore 1st arg) */
  839.           if ($1 != Y_DIV_OP && $1 != Y_DIVU_OP)
  840.             yyerror ("Syntax error");
  841.           r_type_inst ($1, 0, $2, $3);
  842.         }
  843.  
  844.     |    DIV_POP        DEST_REG    SRC1        SRC2
  845.         {
  846.           /* Pseudo divide operations */
  847.           div_inst ($1, $2, $3, $4, 0);
  848.         }
  849.  
  850.     |    DIV_POP        DEST_REG    SRC1        IMM
  851.         {
  852.           if (zero_imm ((imm_expr *)$4))
  853.             yyerror ("Divide by zero");
  854.           else
  855.             {
  856.               /* Use $at */
  857.               i_type_inst_free (Y_ORI_OP, 1, 0, (imm_expr *)$4);
  858.               div_inst ($1, $2, $3, 1, 1);
  859.             }
  860.         }
  861.  
  862.  
  863.     |    MUL_POP        DEST_REG    SRC1        SRC2
  864.         {
  865.           mult_inst ($1, $2, $3, $4);
  866.         }
  867.  
  868.     |    MUL_POP        DEST_REG    SRC1        IMM
  869.         {
  870.           if (zero_imm ((imm_expr *)$4))
  871.             r_type_inst (Y_ORI_OP, $2, 0, 0);
  872.           else
  873.             {
  874.               /* Use $at */
  875.               i_type_inst_free (Y_ORI_OP, 1, 0, (imm_expr *)$4);
  876.               mult_inst ($1, $2, $3, 1);
  877.             }
  878.         }
  879.  
  880.  
  881.     |    MULT_OP        SRC1    SRC2
  882.         {
  883.           r_type_inst ($1, 0, $2, $3);
  884.         }
  885.  
  886.  
  887.     |    Y_ROR_POP    DEST_REG    SRC1        SRC2
  888.         {
  889.           r_type_inst (Y_SUBU_OP, 1, 0, $4);
  890.           r_type_inst (Y_SLLV_OP, 1, 1, $3);
  891.           r_type_inst (Y_SRLV_OP, $2, $4, $3);
  892.           r_type_inst (Y_OR_OP, $2, $2, 1);
  893.         }
  894.  
  895.  
  896.     |    Y_ROL_POP    DEST_REG    SRC1        SRC2
  897.         {
  898.           r_type_inst (Y_SUBU_OP, 1, 0, $4);
  899.           r_type_inst (Y_SRLV_OP, 1, 1, $3);
  900.           r_type_inst (Y_SLLV_OP, $2, $4, $3);
  901.           r_type_inst (Y_OR_OP, $2, $2, 1);
  902.         }
  903.  
  904.  
  905.     |    Y_ROR_POP    DEST_REG    SRC1        IMM
  906.         {
  907.           long dist = eval_imm_expr ((imm_expr *)$4);
  908.  
  909.           r_sh_type_inst (Y_SLL_OP, 1, $3, -dist);
  910.           r_sh_type_inst (Y_SRL_OP, $2, $3, dist);
  911.           r_type_inst (Y_OR_OP, $2, $2, 1);
  912.           free ((imm_expr *)$4);
  913.         }
  914.  
  915.  
  916.     |    Y_ROL_POP    DEST_REG    SRC1        IMM
  917.         {
  918.           long dist = eval_imm_expr ((imm_expr *)$4);
  919.  
  920.           r_sh_type_inst (Y_SRL_OP, 1, $3, -dist);
  921.           r_sh_type_inst (Y_SLL_OP, $2, $3, dist);
  922.           r_type_inst (Y_OR_OP, $2, $2, 1);
  923.           free ((imm_expr *)$4);
  924.         }
  925.  
  926.  
  927.  
  928.     |    SET_LE_POP    DEST_REG    SRC1        SRC2
  929.         {
  930.           set_le_inst ($1, $2, $3, $4);
  931.         }
  932.  
  933.     |    SET_LE_POP    DEST_REG    SRC1        IMM
  934.         {
  935.           if (!zero_imm ((imm_expr *)$4))
  936.             /* Use $at */
  937.             i_type_inst (Y_ORI_OP, 1, 0, (imm_expr *)$4);
  938.           set_le_inst ($1, $2, $3, (zero_imm ((imm_expr *)$4) ? 0 : 1));
  939.           free ((imm_expr *)$4);
  940.         }
  941.  
  942.  
  943.     |    SET_GT_POP    DEST_REG    SRC1        SRC2
  944.         {
  945.           set_gt_inst ($1, $2, $3, $4);
  946.         }
  947.  
  948.     |    SET_GT_POP    DEST_REG    SRC1        IMM
  949.         {
  950.           if (!zero_imm ((imm_expr *)$4))
  951.             /* Use $at */
  952.             i_type_inst (Y_ORI_OP, 1, 0, (imm_expr *)$4);
  953.           set_gt_inst ($1, $2, $3, (zero_imm ((imm_expr *)$4) ? 0 : 1));
  954.           free ((imm_expr *)$4);
  955.         }
  956.  
  957.  
  958.  
  959.     |    SET_GE_POP    DEST_REG    SRC1        SRC2
  960.         {
  961.           set_ge_inst ($1, $2, $3, $4);
  962.         }
  963.  
  964.     |    SET_GE_POP    DEST_REG    SRC1        IMM
  965.         {
  966.           if (!zero_imm ((imm_expr *)$4))
  967.             /* Use $at */
  968.             i_type_inst (Y_ORI_OP, 1, 0, (imm_expr *)$4);
  969.           set_ge_inst ($1, $2, $3, (zero_imm ((imm_expr *)$4) ? 0 : 1));
  970.           free ((imm_expr *)$4);
  971.         }
  972.  
  973.  
  974.     |    SET_EQ_POP    DEST_REG    SRC1        SRC2
  975.         {
  976.           set_eq_inst ($1, $2, $3, $4);
  977.         }
  978.  
  979.     |    SET_EQ_POP    DEST_REG    SRC1        IMM
  980.         {
  981.           if (!zero_imm ((imm_expr *)$4))
  982.             /* Use $at */
  983.             i_type_inst (Y_ORI_OP, 1, 0, (imm_expr *)$4);
  984.           set_eq_inst ($1, $2, $3, (zero_imm ((imm_expr *)$4) ? 0 : 1));
  985.           free ((imm_expr *)$4);
  986.         }
  987.  
  988.  
  989.     |    NULLARY_BR_OP    LABEL
  990.         {
  991.           i_type_inst_free ($1, 0, 0, (imm_expr *)$2);
  992.         }
  993.  
  994.  
  995.     |    UNARY_BR_OP    SRC1        LABEL
  996.         {
  997.           i_type_inst_free ($1, 0, $2, (imm_expr *)$3);
  998.         }
  999.  
  1000.  
  1001.     |    UNARY_BR_POP    SRC1        LABEL
  1002.         {
  1003.           i_type_inst_free ($1 == Y_BEQZ_POP ? Y_BEQ_OP : Y_BNE_OP,
  1004.                    0, $2, (imm_expr *)$3);
  1005.         }
  1006.  
  1007.  
  1008.     |    BINARY_BR_OP    SRC1        SRC2        LABEL
  1009.         {
  1010.           i_type_inst_free ($1, $3, $2, (imm_expr *)$4);
  1011.         }
  1012.  
  1013.     |    BINARY_BR_OP    SRC1        IMMEDIATE    LABEL
  1014.         {
  1015.           if (bare_machine)
  1016.             yyerror ("Immediate form not allowed in bare machine");
  1017.           else
  1018.             {
  1019.               if (zero_imm ((imm_expr *)$3))
  1020.             i_type_inst ($1, $2, (zero_imm ((imm_expr *)$3) ? 0 : 1),
  1021.                      (imm_expr *)$4);
  1022.               else
  1023.             {
  1024.               /* Use $at */
  1025.               i_type_inst (Y_ORI_OP, 1, 0, (imm_expr *)$3);
  1026.               i_type_inst ($1, $2, (zero_imm ((imm_expr *)$3) ? 0 : 1),
  1027.                        (imm_expr *)$4);
  1028.             }
  1029.             }
  1030.           free ((imm_expr *)$3);
  1031.           free ((imm_expr *)$4);
  1032.         }
  1033.  
  1034.  
  1035.     |    BR_GT_POP    SRC1        SRC2        LABEL
  1036.         {
  1037.           r_type_inst ($1 == Y_BGT_POP ? Y_SLT_OP : Y_SLTU_OP,
  1038.                    1, $3, $2); /* Use $at */
  1039.           i_type_inst_free (Y_BNE_OP, 0, 1, (imm_expr *)$4);
  1040.         }
  1041.  
  1042.     |    BR_GT_POP    SRC1        IMMEDIATE    LABEL
  1043.         {
  1044.           if ($1 == Y_BGT_POP)
  1045.             {
  1046.               /* Use $at */
  1047.               i_type_inst_free (Y_SLTI_OP, 1, $2,
  1048.                     incr_expr_offset ((imm_expr *)$3, 1));
  1049.               i_type_inst (Y_BEQ_OP, 0, 1, (imm_expr *)$4);
  1050.             }
  1051.           else
  1052.             {
  1053.               /* Use $at */
  1054.               /* Can't add 1 to immediate since 0xffffffff+1 = 0 < 1 */
  1055.               i_type_inst (Y_ORI_OP, 1, 0, (imm_expr *)$3);
  1056.               i_type_inst_free (Y_BEQ_OP, $2, 1, branch_offset (3));
  1057.               r_type_inst (Y_SLTU_OP, 1, $2, 1);
  1058.               i_type_inst (Y_BEQ_OP, 0, 1, (imm_expr *)$4);
  1059.             }
  1060.           free ((imm_expr *)$3);
  1061.           free ((imm_expr *)$4);
  1062.         }
  1063.  
  1064.  
  1065.     |    BR_GE_POP    SRC1        SRC2        LABEL
  1066.         {
  1067.           r_type_inst ($1 == Y_BGE_POP ? Y_SLT_OP : Y_SLTU_OP,
  1068.                    1, $2, $3); /* Use $at */
  1069.           i_type_inst_free (Y_BEQ_OP, 0, 1, (imm_expr *)$4);
  1070.         }
  1071.  
  1072.     |    BR_GE_POP    SRC1        IMMEDIATE    LABEL
  1073.         {
  1074.           i_type_inst ($1 == Y_BGE_POP ? Y_SLTI_OP : Y_SLTIU_OP,
  1075.                    1, $2, (imm_expr *)$3); /* Use $at */
  1076.           i_type_inst_free (Y_BEQ_OP, 0, 1, (imm_expr *)$4);
  1077.           free ((imm_expr *)$3);
  1078.         }
  1079.  
  1080.  
  1081.     |    BR_LT_POP    SRC1        SRC2        LABEL
  1082.         {
  1083.           r_type_inst ($1 == Y_BLT_POP ? Y_SLT_OP : Y_SLTU_OP,
  1084.                    1, $2, $3); /* Use $at */
  1085.           i_type_inst_free (Y_BNE_OP, 0, 1, (imm_expr *)$4);
  1086.         }
  1087.  
  1088.     |    BR_LT_POP    SRC1        IMMEDIATE    LABEL
  1089.         {
  1090.           i_type_inst ($1 == Y_BLT_POP ? Y_SLTI_OP : Y_SLTIU_OP,
  1091.                    1, $2, (imm_expr *)$3); /* Use $at */
  1092.           i_type_inst_free (Y_BNE_OP, 0, 1, (imm_expr *)$4);
  1093.           free ((imm_expr *)$3);
  1094.         }
  1095.  
  1096.  
  1097.     |    BR_LE_POP    SRC1        SRC2        LABEL
  1098.         {
  1099.           r_type_inst ($1 == Y_BLE_POP ? Y_SLT_OP : Y_SLTU_OP,
  1100.                    1, $3, $2); /* Use $at */
  1101.           i_type_inst_free (Y_BEQ_OP, 0, 1, (imm_expr *)$4);
  1102.         }
  1103.  
  1104.     |    BR_LE_POP    SRC1        IMMEDIATE    LABEL
  1105.         {
  1106.           if ($1 == Y_BLE_POP)
  1107.             {
  1108.               /* Use $at */
  1109.               i_type_inst_free (Y_SLTI_OP, 1, $2,
  1110.                     incr_expr_offset ((imm_expr *)$3, 1));
  1111.               i_type_inst (Y_BNE_OP, 0, 1, (imm_expr *)$4);
  1112.             }
  1113.           else
  1114.             {
  1115.               /* Use $at */
  1116.               /* Can't add 1 to immediate since 0xffffffff+1 = 0 < 1 */
  1117.               i_type_inst (Y_ORI_OP, 1, 0, (imm_expr *)$3);
  1118.               i_type_inst (Y_BEQ_OP, $2, 1, (imm_expr *)$4);
  1119.               r_type_inst (Y_SLTU_OP, 1, $2, 1);
  1120.               i_type_inst (Y_BNE_OP, 0, 1, (imm_expr *)$4);
  1121.             }
  1122.           free ((imm_expr *)$3);
  1123.           free ((imm_expr *)$4);
  1124.         }
  1125.  
  1126.  
  1127.     |    J_OPS        LABEL
  1128.         {
  1129.           if (($1 == Y_J_OP) || ($1 == Y_JR_OP))
  1130.             j_type_inst (Y_J_OP, (imm_expr *)$2);
  1131.           else if (($1 == Y_JAL_OP) || ($1 == Y_JALR_OP))
  1132.             j_type_inst (Y_JAL_OP, (imm_expr *)$2);
  1133.           free ((imm_expr *)$2);
  1134.         }
  1135.  
  1136.  
  1137.     |    J_OPS        SRC1
  1138.         {
  1139.           if (($1 == Y_J_OP) || ($1 == Y_JR_OP))
  1140.             r_type_inst (Y_JR_OP, 0, $2, 0);
  1141.           else if (($1 == Y_JAL_OP) || ($1 == Y_JALR_OP))
  1142.             r_type_inst (Y_JALR_OP, 31, $2, 0);
  1143.         }
  1144.  
  1145.  
  1146.     |    J_OPS        DEST        SRC1
  1147.         {
  1148.           if (($1 == Y_J_OP) || ($1 == Y_JR_OP))
  1149.             r_type_inst (Y_JR_OP, 0, $3, 0);
  1150.           else if (($1 == Y_JAL_OP) || ($1 == Y_JALR_OP))
  1151.             r_type_inst (Y_JALR_OP, $2, $3, 0);
  1152.         }
  1153.  
  1154.  
  1155.     |    B_OP        LABEL
  1156.         {
  1157.           i_type_inst_free (($1 == Y_BAL_POP ? Y_BGEZAL_OP : Y_BGEZ_OP),
  1158.                     0, 0, (imm_expr *)$2);
  1159.         }
  1160.  
  1161.  
  1162.  
  1163.     |    MOVE_COP_OP    COP_REG        COP_REG
  1164.         {
  1165.           r_type_inst ($1, $2, $3, 0);
  1166.         }
  1167.  
  1168.  
  1169.     |    MOV_FROM_HILO_OP    REG
  1170.         {
  1171.           r_type_inst ($1, $2, 0, 0);
  1172.         }
  1173.  
  1174.  
  1175.     |    MOV_TO_HILO_OP    REG
  1176.         {
  1177.           r_type_inst ($1, 0, $2, 0);
  1178.         }
  1179.  
  1180.  
  1181.     |    MOV_COP_OP    REG        COP_REG
  1182.         {
  1183.           if ($1 == Y_MFC1_D_POP)
  1184.             {
  1185.               r_type_inst (Y_MFC1_OP, $3, 0, $2);
  1186.               r_type_inst (Y_MFC1_OP, $3 + 1, 0, $2 + 1);
  1187.             }
  1188.           else if ($1 == Y_MTC1_D_POP)
  1189.             {
  1190.               r_type_inst (Y_MTC1_OP, $3, 0, $2);
  1191.               r_type_inst (Y_MTC1_OP, $3 + 1, 0, $2 + 1);
  1192.             }
  1193.           else
  1194.             r_type_inst ($1, $3, 0, $2);
  1195.         }
  1196.  
  1197.  
  1198.     |    CTL_COP_OP    COP_REG        COP_REG
  1199.         {
  1200.           r_type_inst ($1, $3, 0, $2);
  1201.         }
  1202.  
  1203.  
  1204.     |    FP_ABS_OP    F_DEST        F_SRC1
  1205.         {
  1206.           r_type_inst ($1, $2, $3, 0);
  1207.         }
  1208.  
  1209.  
  1210.     |    FP_BINARY_OP    F_DEST        F_SRC1        F_SRC2
  1211.         {
  1212.           r_type_inst ($1, $2, $3, $4);
  1213.         }
  1214.  
  1215.  
  1216.     |    FP_CONVERT_OP    F_DEST        F_SRC2
  1217.         {
  1218.           r_type_inst ($1, $2, $3, 0);
  1219.         }
  1220.  
  1221.  
  1222.     |    FP_NEG_OP    F_DEST        F_SRC2
  1223.         {
  1224.           r_type_inst ($1, $2, $3, 0);
  1225.         }
  1226.  
  1227.  
  1228.     |    FP_CMP_OP    F_SRC1        F_SRC2
  1229.         {
  1230.           r_cond_type_inst ($1, $2, $3);
  1231.         }
  1232.     ;
  1233.  
  1234.  
  1235.  
  1236. LOAD_OP:    Y_LB_OP
  1237.     |    Y_LBU_OP
  1238.     |    Y_LH_OP
  1239.     |    Y_LHU_OP
  1240.     |    Y_LW_OP
  1241.     |    Y_LWL_OP
  1242.     |    Y_LWR_OP
  1243.     |    Y_LD_POP
  1244.         |       Y_PFW_OP
  1245.     ;
  1246.  
  1247. LOAD_COP:    Y_LWC0_OP
  1248.     |    Y_LWC2_OP
  1249.     |    Y_LWC3_OP
  1250.     ;
  1251.  
  1252. LOAD_IMM_OP:    Y_LUI_OP;
  1253.  
  1254.  
  1255. ULOADH_POP:    Y_ULH_POP
  1256.     |    Y_ULHU_POP
  1257.     ;
  1258.  
  1259. LOADF_OP:    Y_LWC1_OP
  1260.     |    Y_L_S_POP
  1261.     |    Y_L_D_POP
  1262.     ;
  1263.  
  1264.  
  1265. STORE_OP:    Y_SB_OP
  1266.     |    Y_SH_OP
  1267.     |    Y_SW_OP
  1268.     |    Y_SWL_OP
  1269.     |    Y_SWR_OP
  1270.     |    Y_SD_POP
  1271.     ;
  1272.  
  1273. STORE_COP:    Y_SWC0_OP
  1274.     |    Y_SWC2_OP
  1275.     |    Y_SWC3_OP
  1276.     ;
  1277.  
  1278. STOREF_OP:    Y_SWC1_OP
  1279.     |    Y_S_S_POP
  1280.     |    Y_S_D_POP
  1281.     ;
  1282.  
  1283.  
  1284. SYS_OP:        Y_RFE_OP
  1285.     |    Y_SYSCALL_OP
  1286.     ;
  1287.  
  1288.  
  1289. /* These binary operations have immediate analogues. */
  1290.  
  1291. BINARY_OP_I:    Y_ADD_OP
  1292.     |    Y_ADDU_OP
  1293.     |    Y_AND_OP
  1294.     |    Y_XOR_OP
  1295.     |    Y_OR_OP
  1296.     |    Y_SLT_OP
  1297.     |    Y_SLTU_OP
  1298.     ;
  1299.  
  1300. BINARY_OPR_I:    Y_SLLV_OP
  1301.     |    Y_SRAV_OP
  1302.     |    Y_SRLV_OP
  1303.     ;
  1304.  
  1305. BINARY_IMM_OP:    Y_ADDI_OP
  1306.     |    Y_ADDIU_OP
  1307.     |    Y_ANDI_OP
  1308.     |    Y_ORI_OP
  1309.     |    Y_XORI_OP
  1310.     |    Y_SLTI_OP
  1311.     |    Y_SLTIU_OP
  1312.     ;
  1313.  
  1314. SHIFT_OP:    Y_SLL_OP
  1315.     |    Y_SRA_OP
  1316.     |    Y_SRL_OP
  1317.     ;
  1318.  
  1319. /* These binary operations do not have immediate analogues. */
  1320.  
  1321. BINARY_OP_NOI:    Y_NOR_OP ;
  1322.  
  1323. SUB_OP:        Y_SUB_OP
  1324.     |    Y_SUBU_OP
  1325.     ;
  1326.  
  1327. DIV_POP:    Y_DIV_OP
  1328.     |    Y_DIVU_OP
  1329.     |    Y_REM_POP
  1330.     |    Y_REMU_POP
  1331.     ;
  1332.  
  1333. MUL_POP:    Y_MUL_POP
  1334.     |    Y_MULO_POP
  1335.     |    Y_MULOU_POP
  1336.     ;
  1337.  
  1338. SET_LE_POP:    Y_SLE_POP
  1339.     |    Y_SLEU_POP
  1340.     ;
  1341.  
  1342. SET_GT_POP:    Y_SGT_POP
  1343.     |    Y_SGTU_POP
  1344.     ;
  1345.  
  1346. SET_GE_POP:    Y_SGE_POP
  1347.     |    Y_SGEU_POP
  1348.     ;
  1349.  
  1350. SET_EQ_POP:    Y_SEQ_POP
  1351.     |    Y_SNE_POP
  1352.     ;
  1353.  
  1354. MULT_OP:    Y_MULT_OP
  1355.     |    Y_MULTU_OP
  1356.     ;
  1357.  
  1358. NULLARY_BR_OP:    Y_BC0T_OP
  1359.     |    Y_BC1T_OP
  1360.     |    Y_BC2T_OP
  1361.     |    Y_BC3T_OP
  1362.     |    Y_BC0F_OP
  1363.     |    Y_BC1F_OP
  1364.     |    Y_BC2F_OP
  1365.     |    Y_BC3F_OP
  1366.     ;
  1367.  
  1368. UNARY_BR_OP:    Y_BGEZ_OP
  1369.     |    Y_BGEZAL_OP
  1370.     |    Y_BGTZ_OP
  1371.     |    Y_BLEZ_OP
  1372.     |    Y_BLTZ_OP
  1373.     |    Y_BLTZAL_OP
  1374.     ;
  1375.  
  1376. UNARY_BR_POP:    Y_BEQZ_POP
  1377.     |    Y_BNEZ_POP
  1378.     ;
  1379.  
  1380. BINARY_BR_OP:    Y_BEQ_OP
  1381.     |    Y_BNE_OP
  1382.     ;
  1383.  
  1384. BR_GT_POP:    Y_BGT_POP
  1385.     |    Y_BGTU_POP
  1386.  
  1387. BR_GE_POP:    Y_BGE_POP
  1388.     |    Y_BGEU_POP
  1389.  
  1390. BR_LT_POP:    Y_BLT_POP
  1391.     |    Y_BLTU_POP
  1392.  
  1393. BR_LE_POP:    Y_BLE_POP
  1394.     |    Y_BLEU_POP
  1395.     ;
  1396.  
  1397. J_OPS:        Y_J_OP
  1398.     |    Y_JR_OP
  1399.     |    Y_JAL_OP
  1400.     |    Y_JALR_OP
  1401.     ;
  1402.  
  1403. B_OP:        Y_B_POP
  1404.     |    Y_BAL_POP
  1405.     ;
  1406.  
  1407. MOVE_COP_OP:    Y_MOV_S_OP
  1408.     |    Y_MOV_D_OP
  1409.     ;
  1410.  
  1411. MOV_FROM_HILO_OP:    Y_MFHI_OP
  1412.     |    Y_MFLO_OP
  1413.     ;
  1414.  
  1415. MOV_TO_HILO_OP:    Y_MTHI_OP
  1416.     |    Y_MTLO_OP
  1417.     ;
  1418.  
  1419. MOV_COP_OP:    Y_MFC0_OP
  1420.     |    Y_MFC1_OP
  1421.     |    Y_MFC1_D_POP
  1422.     |    Y_MFC2_OP
  1423.     |    Y_MFC3_OP
  1424.     |    Y_MTC0_OP
  1425.     |    Y_MTC1_OP
  1426.     |    Y_MTC1_D_POP
  1427.     |    Y_MTC2_OP
  1428.     |    Y_MTC3_OP
  1429.     ;
  1430.  
  1431. CTL_COP_OP:    Y_CFC0_OP
  1432.     |    Y_CFC1_OP
  1433.     |    Y_CFC2_OP
  1434.     |    Y_CFC3_OP
  1435.     |    Y_CTC0_OP
  1436.     |    Y_CTC1_OP
  1437.     |    Y_CTC2_OP
  1438.     |    Y_CTC3_OP
  1439.     ;
  1440.  
  1441. FP_ABS_OP:    Y_ABS_S_OP
  1442.     |    Y_ABS_D_OP
  1443.     ;
  1444.  
  1445. FP_BINARY_OP:    Y_ADD_S_OP
  1446.     |    Y_ADD_D_OP
  1447.     |    Y_DIV_S_OP
  1448.     |    Y_DIV_D_OP
  1449.     |    Y_MUL_S_OP
  1450.     |    Y_MUL_D_OP
  1451.     |    Y_SUB_S_OP
  1452.     |    Y_SUB_D_OP
  1453.     ;
  1454.  
  1455. FP_CONVERT_OP:    Y_CVT_D_S_OP
  1456.     |    Y_CVT_D_W_OP
  1457.     |    Y_CVT_S_D_OP
  1458.     |    Y_CVT_S_W_OP
  1459.     |    Y_CVT_W_D_OP
  1460.     |    Y_CVT_W_S_OP
  1461.     ;
  1462.  
  1463. FP_NEG_OP:    Y_NEG_S_OP
  1464.     |    Y_NEG_D_OP
  1465.     ;
  1466.  
  1467. FP_CMP_OP:    Y_C_F_S_OP
  1468.     |    Y_C_UN_S_OP
  1469.     |    Y_C_EQ_S_OP
  1470.     |    Y_C_UEQ_S_OP
  1471.     |    Y_C_OLE_S_OP
  1472.     |    Y_C_ULE_S_OP
  1473.     |    Y_C_SF_S_OP
  1474.     |    Y_C_NGLE_S_OP
  1475.     |    Y_C_SEQ_S_OP
  1476.     |    Y_C_NGL_S_OP
  1477.     |    Y_C_LT_S_OP
  1478.     |    Y_C_NGE_S_OP
  1479.     |    Y_C_LE_S_OP
  1480.     |    Y_C_NGT_S_OP
  1481.     |    Y_C_F_D_OP
  1482.     |    Y_C_UN_D_OP
  1483.     |    Y_C_EQ_D_OP
  1484.     |    Y_C_UEQ_D_OP
  1485.     |    Y_C_OLE_D_OP
  1486.     |    Y_C_ULE_D_OP
  1487.     |    Y_C_SF_D_OP
  1488.     |    Y_C_NGLE_D_OP
  1489.     |    Y_C_SEQ_D_OP
  1490.     |    Y_C_NGL_D_OP
  1491.     |    Y_C_LT_D_OP
  1492.     |    Y_C_NGE_D_OP
  1493.     |    Y_C_LE_D_OP
  1494.     |    Y_C_NGT_D_OP
  1495.     ;
  1496.  
  1497.  
  1498.  
  1499. ASM_DIRECTIVE:    Y_ALIAS_DIR    Y_REG    Y_REG
  1500.  
  1501.     |    Y_ALIGN_DIR    EXPR
  1502.         {
  1503.           align_data ($2);
  1504.         }
  1505.  
  1506.     |    Y_ASCII_DIR {null_term = 0;}    STR_LST
  1507.         {
  1508.           if (text_dir)
  1509.             yyerror ("Can't put data in text segment");
  1510.         }
  1511.  
  1512.     |    Y_ASCIIZ_DIR {null_term = 1;}    STR_LST
  1513.         {
  1514.           if (text_dir)
  1515.             yyerror ("Can't put data in text segment");
  1516.         }
  1517.  
  1518.  
  1519.     |    Y_ASM0_DIR
  1520.  
  1521.     |    Y_BGNB_DIR    Y_INT
  1522.  
  1523.  
  1524.     |    Y_BYTE_DIR
  1525.         {store_op = store_byte;}
  1526.         EXPR_LST
  1527.         {
  1528.           if (text_dir)
  1529.             yyerror ("Can't put data in text segment");
  1530.         }
  1531.  
  1532.  
  1533.     |    Y_COMM_DIR    ID        EXPR
  1534.         {
  1535.           align_data (2);
  1536.           if (lookup_label ((char *)$2)->addr == 0)
  1537.             record_label ((char *)$2, current_data_pc ());
  1538.           increment_data_pc ($3);
  1539.         }
  1540.  
  1541.  
  1542.     |    Y_DATA_DIR
  1543.         {
  1544.           user_kernel_data_segment (0);
  1545.           data_dir = 1; text_dir = 0;
  1546.           enable_data_alignment ();
  1547.         }
  1548.  
  1549.     |    Y_DATA_DIR    Y_INT
  1550.         {
  1551.           user_kernel_data_segment (0);
  1552.           data_dir = 1; text_dir = 0;
  1553.           enable_data_alignment ();
  1554.           set_data_pc ($2);
  1555.         }
  1556.  
  1557.  
  1558.     |    Y_K_DATA_DIR
  1559.         {
  1560.           user_kernel_data_segment (1);
  1561.           data_dir = 1; text_dir = 0;
  1562.           enable_data_alignment ();
  1563.         }
  1564.  
  1565.     |    Y_K_DATA_DIR    Y_INT
  1566.         {
  1567.           user_kernel_data_segment (1);
  1568.           data_dir = 1; text_dir = 0;
  1569.           enable_data_alignment ();
  1570.           set_data_pc ($2);
  1571.         }
  1572.  
  1573.  
  1574.     |    Y_DOUBLE_DIR
  1575.         {
  1576.           store_op = store_double;
  1577.           if (data_dir) set_data_alignment(3);
  1578.         }
  1579.         FP_EXPR_LST
  1580.         {
  1581.           if (text_dir)
  1582.             yyerror ("Can't put data in text segment");
  1583.         }
  1584.  
  1585.  
  1586.     |    Y_END_DIR    OPTIONAL_ID
  1587.  
  1588.     |    Y_ENDB_DIR    Y_INT
  1589.  
  1590.     |    Y_ENDR_DIR
  1591.  
  1592.     |    Y_ENT_DIR    ID
  1593.  
  1594.     |    Y_ENT_DIR    ID        Y_INT
  1595.  
  1596.  
  1597.     |    Y_EXTERN_DIR    ID        EXPR
  1598.         {
  1599.           extern_directive ((char *)$2, $3);
  1600.         }
  1601.  
  1602.  
  1603.     |    Y_ERR_DIR
  1604.         {
  1605.           fatal_error ("File contains an .err directive\n");
  1606.         }
  1607.  
  1608.  
  1609.     |    Y_FILE_DIR    Y_INT        Y_STR
  1610.  
  1611.  
  1612.     |    Y_FLOAT_DIR
  1613.         {
  1614.           store_op = store_float;
  1615.           if (data_dir) set_data_alignment (2);
  1616.         }
  1617.         FP_EXPR_LST
  1618.         {
  1619.           if (text_dir)
  1620.             yyerror ("Can't put data in text segment");
  1621.         }
  1622.  
  1623.  
  1624.     |    Y_FMASK_DIR    Y_INT        Y_INT
  1625.  
  1626.     |    Y_FRAME_DIR    REGISTER    Y_INT    REGISTER
  1627.  
  1628.  
  1629.     |    Y_GLOBAL_DIR    ID
  1630.         {
  1631.           make_label_global ((char *)$2);
  1632.         }
  1633.  
  1634.  
  1635.     |    Y_HALF_DIR
  1636.         {
  1637.           store_op = store_half;
  1638.           if (data_dir) set_data_alignment (1);
  1639.         }
  1640.         EXPR_LST
  1641.         {
  1642.           if (text_dir)
  1643.             yyerror ("Can't put data in text segment");
  1644.         }
  1645.  
  1646.  
  1647.     |    Y_LABEL_DIR    ID
  1648.         {
  1649.           record_label ((char *)$2, (text_dir ? current_text_pc ()
  1650.                          : current_data_pc ()));
  1651.         }
  1652.  
  1653.  
  1654.     |    Y_LCOMM_DIR    ID        EXPR
  1655.         {
  1656.           lcomm_directive ((char *)$2, $3);
  1657.         }
  1658.  
  1659.  
  1660.         /* Produced by cc 2.10 */
  1661.     |    Y_LIVEREG_DIR    Y_INT        Y_INT
  1662.  
  1663.  
  1664.     |    Y_LOC_DIR    Y_INT        Y_INT
  1665.  
  1666.     |    Y_MASK_DIR    Y_INT        Y_INT
  1667.  
  1668.     |    Y_NOALIAS_DIR    Y_REG    Y_REG
  1669.  
  1670.     |    Y_OPTIONS_DIR    ID
  1671.  
  1672.     |    Y_REPEAT_DIR    EXPR
  1673.         {
  1674.           yyerror ("Warning: repeat directive ignored");
  1675.         }
  1676.  
  1677.  
  1678.     |    Y_RDATA_DIR
  1679.         {
  1680.           user_kernel_data_segment (0);
  1681.           data_dir = 1; text_dir = 0;
  1682.           enable_data_alignment ();
  1683.         }
  1684.  
  1685.     |    Y_RDATA_DIR    Y_INT
  1686.         {
  1687.           user_kernel_data_segment (0);
  1688.           data_dir = 1; text_dir = 0;
  1689.           enable_data_alignment ();
  1690.           set_data_pc ($2);
  1691.         }
  1692.  
  1693.  
  1694.     |    Y_SDATA_DIR
  1695.         {
  1696.           user_kernel_data_segment (0);
  1697.           data_dir = 1; text_dir = 0;
  1698.           enable_data_alignment ();
  1699.         }
  1700.  
  1701.     |    Y_SDATA_DIR    Y_INT
  1702.         {
  1703.           user_kernel_data_segment (0);
  1704.           data_dir = 1; text_dir = 0;
  1705.           enable_data_alignment ();
  1706.           set_data_pc ($2);
  1707.         }
  1708.  
  1709.  
  1710.     |    Y_SET_DIR        ID
  1711.         {
  1712.           if (streq ((char *)$2, "noat"))
  1713.             noat_flag = 1;
  1714.           else if (streq ((char *)$2, "at"))
  1715.             noat_flag = 0;
  1716.         }
  1717.  
  1718.  
  1719.     |    Y_SPACE_DIR    EXPR
  1720.         {
  1721.           if (data_dir)
  1722.             increment_data_pc ($2);
  1723.           else if (text_dir)
  1724.             increment_text_pc ($2);
  1725.         }
  1726.  
  1727.  
  1728.     |    Y_STRUCT_DIR    EXPR
  1729.         {
  1730.           yyerror ("Warning: struct directive ignored");
  1731.         }
  1732.  
  1733.  
  1734.     |    Y_TEXT_DIR
  1735.         {
  1736.           user_kernel_text_segment (0);
  1737.           data_dir = 0; text_dir = 1;
  1738.           enable_data_alignment ();
  1739.         }
  1740.  
  1741.     |    Y_TEXT_DIR    Y_INT
  1742.         {
  1743.           user_kernel_text_segment (0);
  1744.           data_dir = 0; text_dir = 1;
  1745.           enable_data_alignment ();
  1746.           set_text_pc ($2);
  1747.         }
  1748.  
  1749.  
  1750.     |    Y_K_TEXT_DIR
  1751.         {
  1752.           user_kernel_text_segment (1);
  1753.           data_dir = 0; text_dir = 1;
  1754.           enable_data_alignment ();
  1755.         }
  1756.  
  1757.     |    Y_K_TEXT_DIR    Y_INT
  1758.         {
  1759.           user_kernel_text_segment (1);
  1760.           data_dir = 0; text_dir = 1;
  1761.           enable_data_alignment ();
  1762.           set_text_pc ($2);
  1763.         }
  1764.  
  1765.  
  1766.     |    Y_VERSTAMP_DIR    Y_INT        Y_INT
  1767.  
  1768.     |    Y_VREG_DIR    REGISTER    Y_INT    Y_INT
  1769.  
  1770.  
  1771.     |    Y_WORD_DIR
  1772.         {
  1773.           store_op = store_word_data;
  1774.           if (data_dir) set_data_alignment (2);
  1775.         }
  1776.         EXPR_LST
  1777.  
  1778.     ;
  1779.  
  1780.  
  1781.  
  1782. ADDRESS:    {only_id = 1;} ADDR {only_id = 0; $$ = $2;}
  1783.  
  1784. ADDR:        '(' REGISTER ')'
  1785.         {
  1786.           $$ = (int) make_addr_expr (0, NULL, $2);
  1787.         }
  1788.  
  1789.     |    ABS_ADDR
  1790.         {
  1791.           $$ = (int) make_addr_expr ($1, NULL, 0);
  1792.         }
  1793.  
  1794.     |    ABS_ADDR '(' REGISTER ')'
  1795.         {
  1796.           $$ = (int) make_addr_expr ($1, NULL, $3);
  1797.         }
  1798.  
  1799.     |    Y_ID
  1800.         {
  1801.           $$ = (int) make_addr_expr (0, (char *)$1, 0);
  1802.           if ($1) free ((char *)$1);
  1803.         }
  1804.  
  1805.     |    Y_ID '(' REGISTER ')'
  1806.         {
  1807.           $$ = (int) make_addr_expr (0, (char *)$1, $3);
  1808.           if ($1) free ((char *)$1);
  1809.         }
  1810.  
  1811.     |    Y_ID '+' ABS_ADDR
  1812.         {
  1813.           $$ = (int) make_addr_expr ($3, (char *)$1, 0);
  1814.           if ($1) free ((char *)$1);
  1815.         }
  1816.  
  1817.     |    ABS_ADDR '+' ID
  1818.         {
  1819.           $$ = (int) make_addr_expr ($1, (char *)$3, 0);
  1820.         }
  1821.  
  1822.     |    Y_ID '-' ABS_ADDR
  1823.         {
  1824.           $$ = (int) make_addr_expr (- $3, (char *)$1, 0);
  1825.           if ($1) free ((char *)$1);
  1826.         }
  1827.  
  1828.     |    Y_ID '+' ABS_ADDR '(' REGISTER ')'
  1829.         {
  1830.           $$ = (int) make_addr_expr ($3, (char *)$1, $5);
  1831.           if ($1) free ((char *)$1);
  1832.         }
  1833.  
  1834.     |    Y_ID '-' ABS_ADDR '(' REGISTER ')'
  1835.         {
  1836.           $$ = (int) make_addr_expr (- $3, (char *)$1, $5);
  1837.           if ($1) free ((char *)$1);
  1838.         }
  1839.     ;
  1840.  
  1841.  
  1842. IMMEDIATE:    {only_id = 1;} IMM {only_id = 0; $$ = $2;}
  1843.  
  1844. IMM:        ABS_ADDR
  1845.         {
  1846.           $$ = (int) make_imm_expr ($1, NULL, 0);
  1847.         }
  1848.  
  1849.     |    '(' ABS_ADDR ')' '>' '>' Y_INT
  1850.         {
  1851.           $$ = (int) make_imm_expr ($2 >> $6, NULL, 0);
  1852.         }
  1853.  
  1854.     |    ID
  1855.         {
  1856.           $$ = (int) make_imm_expr (0, (char *)$1, 0);
  1857.         }
  1858.  
  1859.     |    Y_ID '+' ABS_ADDR
  1860.         {
  1861.           $$ = (int) make_imm_expr ($3, (char *)$1, 0);
  1862.           free ((char *)$1);
  1863.         }
  1864.  
  1865.     |    Y_ID '-' ABS_ADDR
  1866.         {
  1867.           $$ = (int) make_imm_expr (- $3, (char *)$1, 0);
  1868.           free ((char *)$1);
  1869.         }
  1870.     ;
  1871.  
  1872.  
  1873. ABS_ADDR:    Y_INT
  1874.  
  1875.     |    Y_INT '+' Y_INT
  1876.         {$$ = $1 + $3;}
  1877.  
  1878.     |    Y_INT Y_INT
  1879.         {
  1880.           /* Y_INT '-' Y_INT */
  1881.           if ($2 >= 0)
  1882.             yyerror ("Syntax error");
  1883.           $$ = $1 - $2;
  1884.         }
  1885.     ;
  1886.  
  1887. DEST_REG:    REGISTER ;
  1888.  
  1889. SRC1:        REGISTER ;
  1890.  
  1891. SRC2:        REGISTER ;
  1892.  
  1893. DEST:        REGISTER ;
  1894.  
  1895. REG:        REGISTER ;
  1896.  
  1897. SOURCE:        REGISTER ;
  1898.  
  1899. REGISTER:    Y_REG
  1900.         {
  1901.           if ($1 < 0 || $1 > 31)
  1902.             yyerror ("Register number out of range");
  1903.           if ($1 == 1 && !bare_machine && !noat_flag)
  1904.             yyerror ("Register 1 is reserved for assembler");
  1905.           $$ = $1;
  1906.         }
  1907.  
  1908. F_DEST:        FP_REGISTER ;
  1909.  
  1910. F_SRC1:        FP_REGISTER ;
  1911.  
  1912. F_SRC2:        FP_REGISTER ;
  1913.  
  1914. FP_REGISTER:    Y_FP_REG
  1915.         {
  1916.           if ($1 < 0 || $1 > 31)
  1917.             yyerror ("FP register number out of range");
  1918.           $$ = $1;
  1919.         }
  1920.  
  1921.  
  1922. COP_REG:    Y_REG
  1923.  
  1924.     |    Y_FP_REG
  1925.  
  1926.     ;
  1927.  
  1928.  
  1929. LABEL:        ID
  1930.         {
  1931.           $$ = (int) make_imm_expr (- current_text_pc (), (char *)$1,
  1932.                         1);
  1933.         }
  1934.  
  1935.  
  1936. STR_LST:    STR_LST STR
  1937.     |    STR
  1938.     ;
  1939.  
  1940.  
  1941. STR:        Y_STR
  1942.         {
  1943.           store_string ((char *)$1, y_str_length, null_term);
  1944.           free ($1);
  1945.         }
  1946.     |    Y_STR ':' Y_INT
  1947.         {
  1948.           int i;
  1949.  
  1950.           for (i = 0; i < $3; i ++)
  1951.             store_string ((char *)$1, y_str_length, null_term);
  1952.           free ($1);
  1953.         }
  1954.     ;
  1955.  
  1956.  
  1957. EXPRESSION:    {only_id = 1;} EXPR {only_id = 0; $$ = $2;}
  1958.  
  1959. EXPR:        Y_INT
  1960.  
  1961.     |    ID
  1962.         {
  1963.           label *l = lookup_label ((char *)$1);
  1964.  
  1965.           if (l->addr == 0)
  1966.             {
  1967.               record_data_uses_symbol (current_data_pc (), l);
  1968.               $$ = 0;
  1969.             }
  1970.           else
  1971.             $$ = l->addr;
  1972.         }
  1973.  
  1974.  
  1975. EXPR_LST:    EXPR_LST    EXPRESSION
  1976.         {
  1977.           store_op ($2);
  1978.         }
  1979.     |    EXPRESSION
  1980.         {
  1981.           store_op ($1);
  1982.         }
  1983.     |    EXPRESSION ':' Y_INT
  1984.         {
  1985.           int i;
  1986.  
  1987.           for (i = 0; i < $3; i ++)
  1988.             store_op ($1);
  1989.         }
  1990.     ;
  1991.  
  1992.  
  1993. FP_EXPR_LST:    FP_EXPR_LST Y_FP
  1994.         {
  1995.           store_op ($2);
  1996.         }
  1997.     |    Y_FP
  1998.         {
  1999.           store_op ($1);
  2000.         }
  2001.     ;
  2002.  
  2003.  
  2004. OPTIONAL_ID:    {only_id = 1;} OPT_ID {only_id = 0; $$ = $2;}
  2005.  
  2006. OPT_ID:        ID
  2007.     |    {$$ = 0;}
  2008.     ;
  2009.  
  2010.  
  2011. ID:        {only_id = 1;} Y_ID {only_id = 0; $$ = $2;}
  2012.  
  2013.  
  2014. %%
  2015.  
  2016. /* Maintain and update the address of labels for the current line. */
  2017.  
  2018. #ifdef __STDC__
  2019. void
  2020. fix_current_label_address (mem_addr new_addr)
  2021. #else
  2022. void
  2023. fix_current_label_address (new_addr)
  2024.      mem_addr new_addr;
  2025. #endif
  2026. {
  2027.   label_list *l;
  2028.  
  2029.   for (l = this_line_labels; l != NULL; l = l->tail)
  2030.     l->head->addr = new_addr;
  2031.   clear_labels ();
  2032. }
  2033.  
  2034.  
  2035. #ifdef __STDC__
  2036. static label_list *
  2037. cons_label (label *head, label_list *tail)
  2038. #else
  2039. static label_list *
  2040. cons_label (head, tail)
  2041.      label *head;
  2042.      label_list *tail;
  2043. #endif
  2044. {
  2045.   label_list *c = (label_list *) malloc (sizeof (label_list));
  2046.  
  2047.   c->head = head;
  2048.   c->tail = tail;
  2049.   return (c);
  2050. }
  2051.  
  2052.  
  2053. #ifdef __STDC__
  2054. static void
  2055. clear_labels (void)
  2056. #else
  2057. static void
  2058. clear_labels ()
  2059. #endif
  2060. {
  2061.   label_list *n;
  2062.  
  2063.   for ( ; this_line_labels != NULL; this_line_labels = n)
  2064.     {
  2065.       n = this_line_labels->tail;
  2066.       free (this_line_labels);
  2067.     }
  2068. }
  2069.  
  2070.  
  2071. /* Operations on op codes. */
  2072.  
  2073. #ifdef __STDC__
  2074. int
  2075. op_to_imm_op (int opcode)
  2076. #else
  2077. int
  2078. op_to_imm_op (opcode)
  2079.      int opcode;
  2080. #endif
  2081. {
  2082.   switch (opcode)
  2083.     {
  2084.     case Y_ADD_OP: return (Y_ADDI_OP);
  2085.     case Y_ADDU_OP: return (Y_ADDIU_OP);
  2086.     case Y_AND_OP: return (Y_ANDI_OP);
  2087.     case Y_OR_OP: return (Y_ORI_OP);
  2088.     case Y_XOR_OP: return (Y_XORI_OP);
  2089.     case Y_SLT_OP: return (Y_SLTI_OP);
  2090.     case Y_SLTU_OP: return (Y_SLTIU_OP);
  2091.     case Y_SLLV_OP: return (Y_SLL_OP);
  2092.     case Y_SRAV_OP: return (Y_SRA_OP);
  2093.     case Y_SRLV_OP: return (Y_SRL_OP);
  2094.     default: fatal_error ("Can't convert op to immediate op\n"); return (0);
  2095.     }
  2096. }
  2097.  
  2098.  
  2099. #ifdef __STDC__
  2100. int
  2101. imm_op_to_op (int opcode)
  2102. #else
  2103. int
  2104. imm_op_to_op (opcode)
  2105.      int opcode;
  2106. #endif
  2107. {
  2108.   switch (opcode)
  2109.     {
  2110.     case Y_ADDI_OP: return (Y_ADD_OP);
  2111.     case Y_ADDIU_OP: return (Y_ADDU_OP);
  2112.     case Y_ANDI_OP: return (Y_AND_OP);
  2113.     case Y_ORI_OP: return (Y_OR_OP);
  2114.     case Y_XORI_OP: return (Y_XOR_OP);
  2115.     case Y_SLTI_OP: return (Y_SLT_OP);
  2116.     case Y_SLTIU_OP: return (Y_SLTU_OP);
  2117.     case Y_J_OP: return (Y_JR_OP);
  2118.     case Y_LUI_OP: return (Y_ADDU_OP);
  2119.     case Y_SLL_OP: return (Y_SLLV_OP);
  2120.     case Y_SRA_OP: return (Y_SRAV_OP);
  2121.     case Y_SRL_OP: return (Y_SRLV_OP);
  2122.     default: fatal_error ("Can't convert immediate op to op\n"); return (0);
  2123.     }
  2124. }
  2125.  
  2126.  
  2127. #ifdef __STDC__
  2128. static void
  2129. nop_inst (void)
  2130. #else
  2131. static void
  2132. nop_inst ()
  2133. #endif
  2134. {
  2135.   r_type_inst (Y_OR_OP, 0, 0, 0);
  2136. }
  2137.  
  2138.  
  2139. #ifdef __STDC__
  2140. static void
  2141. trap_inst (void)
  2142. #else
  2143. static void
  2144. trap_inst ()
  2145. #endif
  2146. {
  2147.   r_type_inst (Y_BREAK_OP, 0, 0, 0);
  2148. }
  2149.  
  2150.  
  2151. #ifdef __STDC__
  2152. static imm_expr *
  2153. branch_offset (int n_inst)
  2154. #else
  2155. static imm_expr *
  2156. branch_offset (n_inst)
  2157.      int n_inst;
  2158. #endif
  2159. {
  2160.   return (const_imm_expr (n_inst << 2)); /* Later shifted right 2 places */
  2161. }
  2162.  
  2163.  
  2164. #ifdef __STDC__
  2165. static void
  2166. div_inst (int op, int rd, int rs, int rt, int const_divisor)
  2167. #else
  2168. static void
  2169. div_inst (op, rd, rs, rt, const_divisor)
  2170.      int op, rd, rs, rt, const_divisor;
  2171. #endif
  2172. {
  2173.   if (rd != 0 && !const_divisor)
  2174.     {
  2175.       i_type_inst_free (Y_BNE_OP, 0, rt, branch_offset (2));
  2176.       trap_inst ();
  2177.     }
  2178.   if (op == Y_DIV_OP || op == Y_REM_POP)
  2179.     r_type_inst (Y_DIV_OP, 0, rs, rt);
  2180.   else
  2181.     r_type_inst (Y_DIVU_OP, 0, rs, rt);
  2182.   if (rd != 0)
  2183.     {
  2184.       if (op == Y_DIV_OP || op == Y_DIVU_OP)
  2185.     r_type_inst (Y_MFLO_OP, rd, 0, 0);
  2186.       else
  2187.     r_type_inst (Y_MFHI_OP, rd, 0, 0);
  2188.     }
  2189. }
  2190.  
  2191.  
  2192. #ifdef __STDC__
  2193. static void
  2194. mult_inst (int op, int rd, int rs, int rt)
  2195. #else
  2196. static void
  2197. mult_inst (op, rd, rs, rt)
  2198.      int op, rd, rs, rt;
  2199. #endif
  2200. {
  2201.   if (op == Y_MULOU_POP)
  2202.     r_type_inst (Y_MULTU_OP, 0, rs, rt);
  2203.   else
  2204.     r_type_inst (Y_MULT_OP, 0, rs, rt);
  2205.   if (op == Y_MULOU_POP && rd != 0)
  2206.     {
  2207.       r_type_inst (Y_MFHI_OP, 1, 0, 0);    /* Use $at */
  2208.       i_type_inst_free (Y_BEQ_OP, 0, 1, branch_offset (2));
  2209.       trap_inst ();
  2210.     }
  2211.   else if (op == Y_MULO_POP && rd != 0)
  2212.     {
  2213.       r_type_inst (Y_MFHI_OP, 1, 0, 0); /* use $at */
  2214.       r_type_inst (Y_MFLO_OP, rd, 0, 0);
  2215.       r_sh_type_inst (Y_SRA_OP, rd, rd, 31);
  2216.       i_type_inst_free (Y_BEQ_OP, rd, 1, branch_offset (2));
  2217.       trap_inst ();
  2218.     }
  2219.   if (rd != 0)
  2220.     r_type_inst (Y_MFLO_OP, rd, 0, 0);
  2221. }
  2222.  
  2223.  
  2224. #ifdef __STDC__
  2225. static void
  2226. set_le_inst (int op, int rd, int rs, int rt)
  2227. #else
  2228. static void
  2229. set_le_inst (op, rd, rs, rt)
  2230.      int op, rd, rs, rt;
  2231. #endif
  2232. {
  2233.   i_type_inst_free (Y_BNE_OP, rs, rt, branch_offset (3));
  2234.   i_type_inst_free (Y_ORI_OP, rd, 0, const_imm_expr (1));
  2235.   i_type_inst_free (Y_BEQ_OP, 0, 0, branch_offset (2));
  2236.   r_type_inst ((op == Y_SLE_POP ? Y_SLT_OP : Y_SLTU_OP), rd, rs, rt);
  2237. }
  2238.  
  2239.  
  2240. #ifdef __STDC__
  2241. static void
  2242. set_gt_inst (int op, int rd, int rs, int rt)
  2243. #else
  2244. static void
  2245. set_gt_inst (op, rd, rs, rt)
  2246.      int op, rd, rs, rt;
  2247. #endif
  2248. {
  2249.   r_type_inst (op == Y_SGT_POP ? Y_SLT_OP : Y_SLTU_OP, rd, rt, rs);
  2250. }
  2251.  
  2252.  
  2253. #ifdef __STDC__
  2254. static void
  2255. set_ge_inst (int op, int rd, int rs, int rt)
  2256. #else
  2257. static void
  2258. set_ge_inst (op, rd, rs, rt)
  2259.      int op, rd, rs, rt;
  2260. #endif
  2261. {
  2262.   i_type_inst_free (Y_BNE_OP, rs, rt, branch_offset (3));
  2263.   i_type_inst_free (Y_ORI_OP, rd, 0, const_imm_expr (1));
  2264.   i_type_inst_free (Y_BEQ_OP, 0, 0, branch_offset (2));
  2265.   r_type_inst (op == Y_SGE_POP ? Y_SLT_OP : Y_SLTU_OP, rd, rt, rs);
  2266. }
  2267.  
  2268.  
  2269. #ifdef __STDC__
  2270. static void
  2271. set_eq_inst (int op, int rd, int rs, int rt)
  2272. #else
  2273. static void
  2274. set_eq_inst (op, rd, rs, rt)
  2275.      int op, rd, rs, rt;
  2276. #endif
  2277. {
  2278.   imm_expr *if_eq, *if_neq;
  2279.  
  2280.   if (op == Y_SEQ_POP)
  2281.     if_eq = const_imm_expr (1), if_neq = const_imm_expr (0);
  2282.   else
  2283.     if_eq = const_imm_expr (0), if_neq = const_imm_expr (1);
  2284.  
  2285.   i_type_inst_free (Y_BEQ_OP, rs, rt, branch_offset (3));
  2286.   /* RD <- 0 (if not equal) */
  2287.   i_type_inst_free (Y_ORI_OP, rd, 0, if_neq);
  2288.   i_type_inst_free (Y_BEQ_OP, 0, 0, branch_offset (2)); /* Branch always */
  2289.   /* RD <- 1 */
  2290.   i_type_inst_free (Y_ORI_OP, rd, 0, if_eq);
  2291. }
  2292.  
  2293.  
  2294. /* Store the value either as a datum or instruction. */
  2295.  
  2296. #ifdef __STDC__
  2297. static void
  2298. store_word_data (int value)
  2299. #else
  2300. static void
  2301. store_word_data (value)
  2302.      int value;
  2303. #endif
  2304. {
  2305.   if (data_dir)
  2306.     store_word (value);
  2307.   else if (text_dir)
  2308.     store_instruction (inst_decode (value));
  2309. }
  2310.  
  2311.  
  2312.  
  2313. #ifdef __STDC__
  2314. void
  2315. initialize_parser (char *file_name)
  2316. #else
  2317. void
  2318. initialize_parser (file_name)
  2319.      char *file_name;
  2320. #endif
  2321. {
  2322.   input_file_name = file_name;
  2323.   only_id = 0;
  2324.   data_dir = 0;
  2325.   text_dir = 1;
  2326. }
  2327.  
  2328.  
  2329. #ifdef __STDC__
  2330. void
  2331. yyerror (char *s)
  2332. #else
  2333. void
  2334. yyerror (s)
  2335.      char *s;
  2336. #endif
  2337. {
  2338.   error ("spim: (parser) %s on line %d of file %s\n",
  2339.      s, line_no, input_file_name);
  2340.   print_erroneous_line ();
  2341. }
  2342.